﻿using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.ServiceLocation;
using SearchScreen.SDK;
using SearchScreen.SDK.Infrastructure;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Xml.Serialization;

namespace SearchScreen.SearchScreenModule.ViewModel
{

    class CriteriaTupleViewModel : IPartImportsSatisfiedNotification, INotifyPropertyChanged
    {
        [ImportMany]
        private List<Lazy<ISearchExpression>> deals= null;

        public IEnumerable<ExpressionWithGroup> Deals { get; private set; }

        public CriteriaTupleViewModel()
        {
            // TODO ASYNCHRONE de la Collectyion arrivant du TreeView & AdditionalCriteria
            var xSer = new XmlSerializer(typeof(SearchMetadata));
            var metadata = (SearchMetadata)xSer.Deserialize(File.OpenText(@"..\..\..\SearchScreen.SDK.Test\Samples\sample.xml"));

            var output = MetadataFactory.GenerateMetadataProxies(metadata);

            Recompose(this, output);

        }

        private void Recompose(CriteriaTupleViewModel CriteriaTupleViewModel, Assembly generatedAssembly)
        {
            var container = new CompositionContainer(
                new AggregateCatalog(
                    new AssemblyCatalog(this.GetType().Assembly),
                    new AssemblyCatalog(generatedAssembly)));

            container.SatisfyImportsOnce(this);
        }

        public void OnImportsSatisfied()
        {
            Application.Current.Dispatcher.BeginInvoke((Action)(() =>
            {

                var groups = this.deals
                    .SelectMany(d => d.Value.GetType().GetCustomAttributes(typeof(GroupAttribute), true)
                        .OfType<GroupAttribute>()
                        .Select(g => new ExpressionWithGroup
                        {
                            Group = g,
                            Expression = d.Value
                        })).ToList();

                this.Deals = groups;
                RaisePropertyChanged("Deals");

            }),
            System.Windows.Threading.DispatcherPriority.Normal);
        }

        private void RaisePropertyChanged(string propertyName)
        {
            var handlers = this.PropertyChanged;
            if (null != handlers)
            {
                handlers(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        internal class ExpressionWithGroup
        {
            public GroupAttribute Group { get; set; }

            public ISearchExpression Expression { get; set; }            
        }

        public ICommand ItemClickedCommand 
        {
            get
            {
                return new DelegateCommand<ExpressionWithGroup>(e =>
                {
                    var evt = ServiceLocator.Current.GetInstance<IEventAggregator>();
                    evt.GetEvent<CriteriaTupleToRequestEditorEvent>().Publish(
                        new CriteriaTupleToRequestEditorPayload(e.Expression)
                       );
                });
            }
        }
    }
}
